package com.kermel.andromeda.clock.view;

import java.util.Calendar;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.ViewSwitcher;

import com.kermel.andromeda.R;
import com.kermel.andromeda.activities.alarm.list.action.ViewMyAlarmsAction;
import com.kermel.andromeda.activities.triggered.TriggeredAlarmActivity;
import com.kermel.andromeda.data.Alarm;
import com.kermel.andromeda.data.AlarmManager;

public class ClockView extends LinearLayout {
    private ClockPM clockPM;
    private View clockWidget;
    private TextView timeView;
    private ImageView alarmIndicator;
    private ViewSwitcher dateViewSwitcher;
    private Button triggerAlarmButton;
    
    private boolean showTriggerButton;
    private boolean neverShowAlarmIndicator;

    public ClockView(Context context) {
        super(context);
        initialize(context);
    }
    
    public ClockView(Context context, AttributeSet attrs) {
        super(context, attrs);
        captureValuesFromAttributes(context, attrs);
        initialize(context);
    }
    
    private void captureValuesFromAttributes(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ClockView);
        
        if (typedArray != null) {
            showTriggerButton = typedArray.getBoolean(R.styleable.ClockView_showTriggerButton, false);
            neverShowAlarmIndicator = typedArray.getBoolean(R.styleable.ClockView_neverShowAlarmIndicator, false);
        }
    }
    
    private void initialize(Context context) {
        
        if (inflateAndAddClockWidgetToView(context))
        {
            storeHandlesToTheClockWidgetParts();
            
            // ClockPM can't be fully initialized until we have a handle on timeView.
            initClockPM(context);
            
            updateClockWidgetWithCurrentTime();
            
            initializeListeners();
            
            adjustBasedOnValuesFromAttributes();
            
            showOrHideAlarmIndicatorBasedOnWhetherAnyAlarmsAreSet();
        }
                
        if (dateViewSwitcherWasDisplayedBasedOnSettings()) {
            clockPM.switchTypeOfDateDisplayBasedOnSettings(dateViewSwitcher);
            updateDateDisplay();
        }
    }
    
    private void initClockPM(Context context) {
        clockPM = new ClockPM(context);
        clockPM.registerTimeView(timeView);
    }
    
    private boolean inflateAndAddClockWidgetToView(Context context) {
        boolean result = false;
        
        removeAllViews();
        
        LayoutInflater inflator = LayoutInflater.from(context);
        clockWidget = inflator.inflate(R.layout.clock, null);
        
        if (clockWidget != null) {
            addView(clockWidget);
            result = true;
        }
        
        return result;
    }
    
    private void updateClockWidgetWithCurrentTime() {
        if (timeView != null) {
            CharSequence currentTimeString = clockPM.getCurrentTimeAsString();
            timeView.setText(currentTimeString);
        }
    }
    
    private void storeHandlesToTheClockWidgetParts() {
        timeView = (TextView)findViewById(R.id.timeView);
        alarmIndicator = (ImageView)findViewById(R.id.alarmIndicator);
        dateViewSwitcher = (ViewSwitcher)findViewById(R.id.dateDisplay);
        triggerAlarmButton = (Button)findViewById(R.id.tempTriggerAlarmButton);
    }
    
    private void initializeListeners() {
        if (triggerAlarmButton != null) {
            if (showTriggerButton)
                triggerAlarmButton.setOnClickListener(new TriggerButtonAction());
        }
    }
    
    private void adjustBasedOnValuesFromAttributes() {
        adjustAlarmIndicator();
        adjustTriggerButton();
    }
    
    private void adjustAlarmIndicator() {
        if (neverShowAlarmIndicator)
            alarmIndicator.setVisibility(INVISIBLE);
    }
    
    private void adjustTriggerButton() {
        if (!showTriggerButton)
            triggerAlarmButton.setVisibility(INVISIBLE);
    }
    
    private void showOrHideAlarmIndicatorBasedOnWhetherAnyAlarmsAreSet() {
        if (neverShowAlarmIndicator)
            return;
    
        updateAlarmVisibility();
        registerOrUnregisterAlarmIndicatorActionBasedOnAlarmIndicatorVisibility();
    }
    
    private void updateAlarmVisibility() {
        boolean hasAlarmsEnabled = AlarmManager.instance.areAnyAlarmsSet();
        int visibility = hasAlarmsEnabled ? VISIBLE : INVISIBLE;
        alarmIndicator.setVisibility(visibility);
    }
    
    private void registerOrUnregisterAlarmIndicatorActionBasedOnAlarmIndicatorVisibility() {
        int visibility = alarmIndicator.getVisibility();
        
        if (visibility == View.VISIBLE) {
            registerAlarmIndicatorAction();
        } else {
            unregisterAlarmIndicatorAction();
        }
    }
    
    private void registerAlarmIndicatorAction() {
        alarmIndicator.setOnClickListener(new ViewMyAlarmsAction(getContext()));
    }
    
    private void unregisterAlarmIndicatorAction() {
        alarmIndicator.setOnClickListener(null);
    }
    
    private boolean dateViewSwitcherWasDisplayedBasedOnSettings() {
        boolean result = false;
        
        if (clockPM.isDateDisplayed()) {
            dateViewSwitcher.setVisibility(VISIBLE);
            result = true;
        } else {
            dateViewSwitcher.setVisibility(GONE);
        }
        
        return result;
    }
    
    private void updateDateDisplay() {
        if (clockPM.isFullDateDisplayed())
            updateFullDateDisplay();
        else if (clockPM.isShortDateDisplayed())
            updateShortDateDisplay();
    }
    
    private void updateFullDateDisplay() {
        String dateString = clockPM.buildFullDateString();
        TextView dateView = getFullDateTextView();
        
        if (dateView != null)
            dateView.setText(dateString);
    }
    
    private TextView getFullDateTextView() {
        TextView dateView = null;
        View currentDateView = null;
        
        currentDateView = findViewById(R.id.fullDateTextView);
        
        if (currentDateView != null && currentDateView instanceof TextView)
            dateView = (TextView)currentDateView;
        
        return dateView;
    }
    
    private void updateShortDateDisplay() {
        Calendar date = Calendar.getInstance();
        int dayOfWeek = date.get(Calendar.DAY_OF_WEEK);
        int viewID = determineDayOfWeekTextViewID(dayOfWeek);
        TextView dateTextView = findDayOfWeekTextView(viewID);
        
        if (dateTextView != null) {
            dateTextView.setVisibility(VISIBLE);
            hideOtherTextViews(viewID);
        }
    }
    
    private int determineDayOfWeekTextViewID(int dayOfWeek) {
        int viewID = -1;
        
        switch (dayOfWeek) {
            case Calendar.SUNDAY:
                viewID = R.id.sundayShortView;
                break;
                
            case Calendar.MONDAY:
                viewID = R.id.mondayShortView;
                break;
                
            case Calendar.TUESDAY:
                viewID = R.id.tuesdayShortView;
                break;
                
            case Calendar.WEDNESDAY:
                viewID = R.id.wednesdayShortView;
                break;
                
            case Calendar.THURSDAY:
                viewID = R.id.thursdayShortView;
                break;
                
            case Calendar.FRIDAY:
                viewID = R.id.fridayShortView;
                break;
                
            case Calendar.SATURDAY:
                viewID = R.id.saturdayShortView;
                break;
        }
        
        return viewID;
    }
    
    private TextView findDayOfWeekTextView(int viewID) {
        TextView dateTextView = null;
        View view = findViewById(viewID);
        
        if (view != null && view instanceof TextView)
            dateTextView = (TextView)view;
        
        return dateTextView;
    }
    
    private void hideOtherTextViews(int viewID) {
        if (viewID != R.id.sundayShortView)
            hideShortDateTextView(R.id.sundayShortView);
        
        if (viewID != R.id.mondayShortView)
            hideShortDateTextView(R.id.mondayShortView);
        
        if (viewID != R.id.tuesdayShortView)
            hideShortDateTextView(R.id.tuesdayShortView);
        
        if (viewID != R.id.wednesdayShortView)
            hideShortDateTextView(R.id.wednesdayShortView);
        
        if (viewID != R.id.thursdayShortView)
            hideShortDateTextView(R.id.thursdayShortView);
        
        if (viewID != R.id.fridayShortView)
            hideShortDateTextView(R.id.fridayShortView);
        
        if (viewID != R.id.saturdayShortView)
            hideShortDateTextView(R.id.saturdayShortView);
    }
    
    private void hideShortDateTextView(int viewID) {
        TextView dateTextView = findDayOfWeekTextView(viewID);
        
        if (dateTextView != null)
            dateTextView.setVisibility(INVISIBLE);
    }
    
    private class TriggerButtonAction implements OnClickListener {
        public void onClick(View v) {
            Intent intent = new Intent(getContext(), TriggeredAlarmActivity.class);
            Alarm alarm = AlarmManager.instance.getAlarmByIndex(0);
            intent.putExtra(Alarm.ALARM_PARCEL_NAME, alarm);
            Context myContext = getContext();
            if (myContext != null && myContext instanceof Activity) {
                Activity myActivity = (Activity)myContext;
                myActivity.startActivity(intent);
            }
        }
    }
}
